package  search

import (
	"fmt"
	"github.com/PuerkitoBio/goquery"
	"io"
	"net/http"
	_  "os"
	"strings"
)
func  displaySearchResult( queryName string )  error {

	  packagesInfo  ,  err := getPackageInfo(queryName)

	if err != nil {
		fmt.Println("请求失败",err)
		return err
	}
      packageVersion ,err := getPackageVersion(packagesInfo)
	packagesName  ,  err := preProcessingNameInfo(packagesInfo  ,queryName) ;
	packagesPath , err  := preProcessingPathInfo(packagesInfo , queryName ) ;
	packagesDescription, err := preProcessingDescriptionInfo(packagesInfo, queryName ) ;
	packageZipped  := make(  [][] string   ,  len(packagesPath  ));
	for   i ,_   :=range   packagesName  {
		pair:=  [] string  { packagesName[i],  packageVersion[i],  packagesPath[i]  , packagesDescription[i]  }
		packageZipped[i] = pair ;
	}

	for    _, info   := range  packageZipped  {
		//if ( info[3] =="") {
		//	fmt.Printf("\x1b[32m %-30s\x1b[0m \x1b[35m\t\x1b[0m\t\t%s \n "  , info[0]+" = "+info[1] , info[2]   )
		//	continue
		//}
		fmt.Printf("\x1b[32m %-30s\x1b[0m \x1b[35m\t\x1b[0m\t\t%-30s \n "  , info[0]+" = "+info[1] , info[2]   )


	}
    return nil
}

func preProcessingDescriptionInfo(info []Package, name string) ([]string  ,error ) {
	  var  description []string

	for  _, info := range info {
		description = append(description, info.Description)
	}
	return description , nil
}

func getPackageVersion(info []Package) ([] string ,error )  {
	  var  version []string
	for  _ , info := range info {
		version = append(version , info.Version)
	}
	return version , nil
}

func preProcessingPathInfo(info []Package  , query string ) ([]string  , error) {
	  var   infoPath [] string

	for _  , info  := range info {
		path := strings.Split(info.Path , "/")[ len(strings.Split(info.Path, "/")) -1]
		if strings.Contains( path  ,  query ) {
			infoPath= append(infoPath , info.Path )
		}
	}
  return infoPath , nil
}

func preProcessingNameInfo(info []Package, query  string) ([]string, error) {
	  var  infoName  []string
	 for  _ ,  name := range info {
		 name := name.Name ;
		  // 按照/ 分割字符串
		  name  =strings.Split(name , "/" )[len(strings.Split(name , "/" )) -1 ];
		   if  strings.Contains(name , query) {
			   infoName= append(infoName , name )
		   }
	}

	return infoName , nil
}


type Package struct {
	Name        string  `json:"name,omitempty"`
	Path        string  `json:"path"`
	Version    string  `json:"version,omitempty"`
	Description     string  `json:"synopsis,omitempty"`
}




func getPackageInfo(name string)  ([]Package  ,error){

	const apiURL = "https://pkg.go.dev/search?limit=50&m=package&q="
	url := apiURL + name // 构建请求URL
	response  ,err:= http.DefaultClient.Get(url)
	 if err != nil {
		fmt.Println("请求失败",err)
		 return   nil, err
	}
	defer func(Body io.ReadCloser) {
		err := Body.Close()
		if err != nil {
			fmt.Println("关闭失败",err)
			return
		}
	}(response.Body) // 函数结束时关闭响应体
	if  response.StatusCode != http.StatusOK {
		fmt.Println("请求失败",err)
		return nil, fmt.Errorf("failed to search package, server return code=%s", response.Status)
	}

	 body  ,err := goquery.NewDocumentFromReader(response.Body)
	 if err != nil {
		fmt.Println("请求失败",err)
		 return nil, err
	 }
	 //fmt.Println(body.Html())
 	var  packageInfo []Package
	 var  path  , desc, version  []string ;
	body.Find(".go-Content.SearchResults .SearchSnippet").Each(func(i int, selection *goquery.Selection) {
		 p := removeQuote(selection.Find(".SearchSnippet-header-path").Text())
		 path = append(path, p)

	})
	body.Find(".SearchSnippet-infoLabel").Each(func(i int , selection *goquery.Selection) {
		//选择第三个子元素
       version1 :=  selection.Find("span").Eq(2).First().Find("strong").First().Text()
		version = append(version, version1)
	})

	body.Find(".SearchSnippet-synopsis").Each(func(i int , selection *goquery.Selection) {
		 description := selection.First().Text()
		 if strings.TrimSpace(description)==""  {
			 description = "No description available"
		 }
		 desc = append(desc, description)
	})
	for i := 0; i < len(path); i++ {
		if   i>= len(desc) {
			desc = append(desc, "")
		}
		packageInfo = append(packageInfo, Package{
			Name:     path[i],
			Path:     path[i],
			Description : desc[i],
			Version : version[i],
		})
	}

	return  packageInfo, nil
}
var _replacer = strings.NewReplacer("(", "", ")", "", " ", "")

func removeQuote(s string) string {
	return _replacer.Replace(s)
}